﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using Sp.WebHost.Logger;
using Sp.WebHost.NetFramework;

namespace Sp.WebHost.SimpleIocp
{
    public class TcpServer : IDisposable
    {
        private readonly int _port;
        private readonly ILogger _logger;
        private Socket _listenSocket; // 用来侦听到达的连接请求的Socket
        private Semaphore _mMaxNumberAcceptedClients; //最大接受请求数信号量

        public TcpServer(int port)
        {
            _port = port;
            _mMaxNumberAcceptedClients = new Semaphore(50,1024);
        }

        public bool Start()
        {
            try
            {
                // 创建一个侦听到达连接的Socket
                var localEndPoint = new IPEndPoint(IPAddress.Any, _port);
                if (null != _listenSocket)
                {
                    _listenSocket.Close();
                }
                else
                {

                    _listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                    _listenSocket.Bind(localEndPoint);
                }
                _listenSocket.Listen(100);
            }
            catch (ObjectDisposedException)
            {
                return false;
            }
            catch (SocketException)
            {
                // 启动失败抛出启动失败异常
                _logger.LogError(null, "服务器启动失败,检查网络环境!");
                return false;
            }
            // 在侦听Socket上抛出接受委托.
            _logger.LogInfo("服务器启动成功......!");
            StartAccept(null);
            return true;
        }

        private void StartAccept(SocketAsyncEventArgs acceptEventArg)
        {
            if (acceptEventArg == null)
            {
                acceptEventArg = new SocketAsyncEventArgs();
                acceptEventArg.Completed += acceptEventArg_Completed;
            }
            else
            {
                // 由于上下文对象正在被使用Socket必须被清理
                acceptEventArg.AcceptSocket = null;
            }
            _mMaxNumberAcceptedClients.WaitOne();//连接数+1
            var willRaiseEvent = _listenSocket.AcceptAsync(acceptEventArg);
            if (!willRaiseEvent)
            {

            }
        }
     

        private void acceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
        {
            if (e.LastOperation == SocketAsyncOperation.Accept)
            {
                var acceptSocket = e.AcceptSocket;

                if (acceptSocket != null)
                {
                    // 处理方法
                }
            }

            StartAccept(e);
        }

        public void Dispose()
        {
            throw new NotImplementedException();
        }
    }
}
